return {
  {
    "stevearc/conform.nvim",
    event = "VeryLazy",
    opts = require "configs.conform",
  },
  -- 快速跳转
  {
    "folke/flash.nvim",
    event = "VeryLazy",
    ---@type Flash.Config
    opts = {},
    -- stylua: ignore
    keys = {
      -- 避免和nvim-surround冲突
      { "ss", mode = { "n", "x", "o" }, function() require("flash").jump() end, desc = "Flash" },
      -- { "S", mode = { "n", "x", "o" }, function() require("flash").treesitter() end, desc = "Flash Treesitter" },
      -- { "r", mode = "o", function() require("flash").remote() end, desc = "Remote Flash" },
      -- { "R", mode = { "o", "x" }, function() require("flash").treesitter_search() end, desc = "Treesitter Search" },
      -- { "<c-s>", mode = { "c" }, function() require("flash").toggle() end, desc = "Toggle Flash Search" },
    },
  },

  -- 包围
  {
    "kylechui/nvim-surround",
    version = "*", -- Use for stability; omit to use `main` branch for the latest features
    event = "VeryLazy",
    config = function()
      require("nvim-surround").setup {
        -- Configuration here, or leave empty to use defaults
      }
    end,
  },

  -- 扩展/收缩选中范围
  {
    "terryma/vim-expand-region",
    event = "VeryLazy",
  },

  -- -- 代码大纲
  -- {
  --   "stevearc/aerial.nvim",
  --   ft = {
  --     "typescript",
  --     "javascript",
  --     "python",
  --     "go",
  --     "rust",
  --     "sh",
  --     "json",
  --     "typescriptreact",
  --     "javascriptreact",
  --     "toml",
  --   },
  --   opts = {},
  --   -- Optional dependencies
  --   dependencies = {
  --     "nvim-treesitter/nvim-treesitter",
  --     "nvim-tree/nvim-web-devicons",
  --   },
  --   config = function()
  --     require("aerial").setup {}
  --     require("telescope").load_extension "aerial"
  --     vim.keymap.set("n", "<leader>a", "<cmd>AerialToggle!<CR>")
  --     vim.api.nvim_set_keymap("n", "<leader>o", "<cmd>Telescope aerial<CR>", { noremap = true, silent = true })
  --   end,
  -- },

  -- 全局查找替换
  {
    "nvim-pack/nvim-spectre",
    cmd = "Spectre",
    opts = {
      open_cmd = "noswapfile vnew",
      replace = {
        cmd = "oxi",
      },
    },
    -- stylua: ignore
    keys = {
      { "<leader>sr", function() require("spectre").open() end, desc = "Replace in files (Spectre)" },
    },
  },

  -- TODO列表
  {
    "folke/todo-comments.nvim",
    cmd = { "TodoTrouble", "TodoTelescope" },
    event = { "BufReadPost", "BufNewFile" },
    config = true,
    -- stylua: ignore
    keys = {
      { "]t",         function() require("todo-comments").jump_next() end, desc = "Next todo comment" },
      { "[t",         function() require("todo-comments").jump_prev() end, desc = "Previous todo comment" },
      { "<leader>st", "<cmd>TodoTelescope<cr>",                            desc = "Todo" },
      { "<leader>sT", "<cmd>TodoTelescope keywords=TODO,FIX,FIXME<cr>",    desc = "Todo/Fix/Fixme" },
    },
  },
  -- 词高亮
  {
    "Mr-LLLLL/interestingwords.nvim",
    keys = { "<leader>m", "<leader>M", "<leader>k", "<leader>K" },
    config = function()
      require("interestingwords").setup {
        colors = { "#aeee00", "#ff0000", "#0000ff", "#b88823", "#ffa724", "#ff2c4b" },
        search_count = true,
        navigation = true,
        search_key = "<leader>m",
        cancel_search_key = "<leader>M",
        color_key = "<leader>k",
        cancel_color_key = "<leader>K",
      }
    end,
  },
  -- AI 代码补全
  -- {
  --   "Exafunction/codeium.nvim",
  --   ft = { "typescript", "javascript", "python", "go", "rust", "sh", "typescriptreact", "javascriptreact" },
  --   dependencies = {
  --     "nvim-lua/plenary.nvim",
  --     "hrsh7th/nvim-cmp",
  --   },
  --   config = function()
  --     require("codeium").setup {}
  --     require("cmp").setup {
  --       sources = {
  --         { name = "codeium" },
  --         { name = "nvim_lsp" },
  --         { name = "luasnip" },
  --         { name = "buffer" },
  --         { name = "nvim_lua" },
  --         { name = "path" },
  --       },
  --     }
  --   end,
  -- },
  -- 美化错误消息列表
  {
    "folke/trouble.nvim",
    opts = {}, -- for default options, refer to the configuration section for custom setup.
    ft = { "typescript", "javascript", "python", "go", "rust", "sh", "typescriptreact", "javascriptreact", "json" },
    cmd = "Trouble",
    dependencies = { "nvim-tree/nvim-web-devicons" },
    keys = {
      {
        "<leader>tR",
        "<cmd>Trouble diagnostics toggle<cr>",
        desc = "Diagnostics (Trouble)",
      },
      {
        "<leader>tr",
        "<cmd>Trouble diagnostics toggle filter.buf=0<cr>",
        desc = "Buffer Diagnostics (Trouble)",
      },
      {
        "<leader>cs",
        "<cmd>Trouble symbols toggle focus=false<cr>",
        desc = "Symbols (Trouble)",
      },
      {
        "<leader>a",
        "<cmd>Trouble symbols toggle focus=false<cr>",
        desc = "Symbols (Trouble)",
      },
      {
        "<leader>cl",
        "<cmd>Trouble lsp toggle focus=false win.position=right<cr>",
        desc = "LSP Definitions / references / ... (Trouble)",
      },
      -- {
      --   "<leader>xL",
      --   "<cmd>Trouble loclist toggle<cr>",
      --   desc = "Location List (Trouble)",
      -- },
      -- {
      --   "<leader>xQ",
      --   "<cmd>Trouble qflist toggle<cr>",
      --   desc = "Quickfix List (Trouble)",
      -- },
    },
  },
  {
    "nvim-tree/nvim-tree.lua",
    cmd = { "NvimTreeToggle", "NvimTreeFocus" },
    config = function(_, opts)
      -- 禁用Ctrl-E快捷键
      local function on_attach(bufnr)
        local api = require "nvim-tree.api"

        local function key_desc(desc)
          return { desc = "nvim-tree: " .. desc, buffer = bufnr, noremap = true, silent = true, nowait = true }
        end

        -- BEGIN_DEFAULT_ON_ATTACH
        vim.keymap.set("n", "<C-]>", api.tree.change_root_to_node, key_desc "CD")
        -- vim.keymap.set('n', '<C-e>',   api.node.open.replace_tree_buffer,   key_desc('Open: In Place'))
        vim.keymap.set("n", "<C-k>", api.node.show_info_popup, key_desc "Info")
        vim.keymap.set("n", "<C-r>", api.fs.rename_sub, key_desc "Rename: Omit Filename")
        vim.keymap.set("n", "<C-t>", api.node.open.tab, key_desc "Open: New Tab")
        vim.keymap.set("n", "<C-v>", api.node.open.vertical, key_desc "Open: Vertical Split")
        vim.keymap.set("n", "<C-x>", api.node.open.horizontal, key_desc "Open: Horizontal Split")
        vim.keymap.set("n", "<BS>", api.node.navigate.parent_close, key_desc "Close Directory")
        vim.keymap.set("n", "<CR>", api.node.open.edit, key_desc "Open")
        vim.keymap.set("n", "<Tab>", api.node.open.preview, key_desc "Open Preview")
        vim.keymap.set("n", ">", api.node.navigate.sibling.next, key_desc "Next Sibling")
        vim.keymap.set("n", "<", api.node.navigate.sibling.prev, key_desc "Previous Sibling")
        vim.keymap.set("n", ".", api.node.run.cmd, key_desc "Run Command")
        vim.keymap.set("n", "-", api.tree.change_root_to_parent, key_desc "Up")
        vim.keymap.set("n", "a", api.fs.create, key_desc "Create File Or Directory")
        vim.keymap.set("n", "bd", api.marks.bulk.delete, key_desc "Delete Bookmarked")
        vim.keymap.set("n", "bt", api.marks.bulk.trash, key_desc "Trash Bookmarked")
        vim.keymap.set("n", "bmv", api.marks.bulk.move, key_desc "Move Bookmarked")
        vim.keymap.set("n", "B", api.tree.toggle_no_buffer_filter, key_desc "Toggle Filter: No Buffer")
        vim.keymap.set("n", "c", api.fs.copy.node, key_desc "Copy")
        vim.keymap.set("n", "C", api.tree.toggle_git_clean_filter, key_desc "Toggle Filter: Git Clean")
        vim.keymap.set("n", "[c", api.node.navigate.git.prev, key_desc "Prev Git")
        vim.keymap.set("n", "]c", api.node.navigate.git.next, key_desc "Next Git")
        vim.keymap.set("n", "d", api.fs.remove, key_desc "Delete")
        vim.keymap.set("n", "D", api.fs.trash, key_desc "Trash")
        vim.keymap.set("n", "E", api.tree.expand_all, key_desc "Expand All")
        vim.keymap.set("n", "e", api.fs.rename_basename, key_desc "Rename: Basename")
        vim.keymap.set("n", "]e", api.node.navigate.diagnostics.next, key_desc "Next Diagnostic")
        vim.keymap.set("n", "[e", api.node.navigate.diagnostics.prev, key_desc "Prev Diagnostic")
        vim.keymap.set("n", "F", api.live_filter.clear, key_desc "Live Filter: Clear")
        vim.keymap.set("n", "f", api.live_filter.start, key_desc "Live Filter: Start")
        vim.keymap.set("n", "g?", api.tree.toggle_help, key_desc "Help")
        vim.keymap.set("n", "gy", api.fs.copy.absolute_path, key_desc "Copy Absolute Path")
        vim.keymap.set("n", "ge", api.fs.copy.basename, key_desc "Copy Basename")
        vim.keymap.set("n", "H", api.tree.toggle_hidden_filter, key_desc "Toggle Filter: Dotfiles")
        vim.keymap.set("n", "I", api.tree.toggle_gitignore_filter, key_desc "Toggle Filter: Git Ignore")
        vim.keymap.set("n", "J", api.node.navigate.sibling.last, key_desc "Last Sibling")
        vim.keymap.set("n", "K", api.node.navigate.sibling.first, key_desc "First Sibling")
        vim.keymap.set("n", "L", api.node.open.toggle_group_empty, key_desc "Toggle Group Empty")
        vim.keymap.set("n", "M", api.tree.toggle_no_bookmark_filter, key_desc "Toggle Filter: No Bookmark")
        vim.keymap.set("n", "m", api.marks.toggle, key_desc "Toggle Bookmark")
        vim.keymap.set("n", "o", api.node.open.edit, key_desc "Open")
        vim.keymap.set("n", "O", api.node.open.no_window_picker, key_desc "Open: No Window Picker")
        vim.keymap.set("n", "p", api.fs.paste, key_desc "Paste")
        vim.keymap.set("n", "P", api.node.navigate.parent, key_desc "Parent Directory")
        vim.keymap.set("n", "q", api.tree.close, key_desc "Close")
        vim.keymap.set("n", "r", api.fs.rename, key_desc "Rename")
        vim.keymap.set("n", "R", api.tree.reload, key_desc "Refresh")
        vim.keymap.set("n", "s", api.node.run.system, key_desc "Run System")
        vim.keymap.set("n", "S", api.tree.search_node, key_desc "Search")
        vim.keymap.set("n", "u", api.fs.rename_full, key_desc "Rename: Full Path")
        vim.keymap.set("n", "U", api.tree.toggle_custom_filter, key_desc "Toggle Filter: Hidden")
        vim.keymap.set("n", "W", api.tree.collapse_all, key_desc "Collapse")
        vim.keymap.set("n", "x", api.fs.cut, key_desc "Cut")
        vim.keymap.set("n", "y", api.fs.copy.filename, key_desc "Copy Name")
        vim.keymap.set("n", "Y", api.fs.copy.relative_path, key_desc "Copy Relative Path")
        vim.keymap.set("n", "<2-LeftMouse>", api.node.open.edit, key_desc "Open")
        vim.keymap.set("n", "<2-RightMouse>", api.tree.change_root_to_node, key_desc "CD")
        -- END_DEFAULT_ON_ATTACH
      end

      dofile(vim.g.base46_cache .. "nvimtree")

      opts.on_attach = on_attach
      opts.view.width = 40

      -- 跟随nvim-tree来修改工作目录
      opts.sync_root_with_cwd = true
      opts.actions = {
        change_dir = {
          global = true
        }
      }

      -- 不跟随打开的文件
      opts.update_focused_file = {
        enable = false,
      }

      require("nvim-tree").setup(opts)
    end,
  },

  -- These are some examples, uncomment them if you want to see them work!
  {
    "neovim/nvim-lspconfig",
    config = function()
      require "configs.lspconfig"
    end,
  },

  -- markdown 渲染得更好看
  {
    "MeanderingProgrammer/markdown.nvim",
    name = "render-markdown", -- Only needed if you have another plugin named markdown.nvim
    -- event = "VeryLazy",
    ft = "markdown",
    dependencies = {
      "nvim-treesitter/nvim-treesitter", -- Mandatory
      "nvim-tree/nvim-web-devicons", -- Optional but recommended
    },
    config = function()
      require("render-markdown").setup {}
    end,
  },

  {
    "f-person/git-blame.nvim",
    -- load the plugin at startup
    event = "VeryLazy",
    -- Because of the keys part, you will be lazy loading this plugin.
    -- The plugin wil only load once one of the keys is used.
    -- If you want to load the plugin at startup, add something like event = "VeryLazy",
    -- or lazy = false. One of both options will work.
    opts = {
      -- your configuration comes here
      -- for example
      enabled = true, -- if you want to enable the plugin
      message_template = "<author> • <date> • <summary> ", -- template for the blame message, check the Message template section for more options
      date_format = "%Y-%m-%d %H:%M:%S", -- template for the date, check Date format section for more options
      virtual_text_column = 1, -- virtual text start column, check Start virtual text at column section for more options
    },
  },
  -- UI美化
  -- {
  --   "rcarriga/nvim-notify",
  --   event = "VeryLazy",
  --   opts = {
  --     -- add any options here
  --     background_colour = "#1a1b26",
  --   },
  -- },
  -- {
  --   "folke/noice.nvim",
  --   event = "VeryLazy",
  --   opts = {},
  --   dependencies = {
  --     -- if you lazy-load any plugin below, make sure to add proper `module="..."` entries
  --     "MunifTanjim/nui.nvim",
  --     -- OPTIONAL:
  --     --   `nvim-notify` is only needed, if you want to use the notification view.
  --     --   If not available, we use `mini` as the fallback
  --     "rcarriga/nvim-notify",
  --   },
  -- },
  -- 鼠标跳跃时候的动画，实际上感觉用处不是很大，而且在高配机器上还是有卡顿
  -- {
  --   "sphamba/smear-cursor.nvim",
  --   event = "VeryLazy",
  --   opts = {},
  -- },

  -- 自动切换输入法,禁用的原因是在切换nvim和其他程序的时候,不会自动恢复输入法配置,导致效率变低
  -- {
  --   "keaising/im-select.nvim",
  --   event = "VeryLazy",
  --   config = function()
  --     require("im_select").setup({})
  --   end,
  -- }
  -- 优化文档注释生成，自动补充参数部分
  {
    "danymat/neogen",
    event = "VeryLazy",
    config = function()
      require("neogen").setup {}
      -- 自动识别标注类型的准确率几乎为零，所以还是手动指定类型吧
      local opts = { noremap = true, silent = true }
      vim.api.nvim_set_keymap("n", "<Leader>dof", ":lua require('neogen').generate({ type='func' })<CR>", opts)
      vim.api.nvim_set_keymap("n", "<Leader>doc", ":lua require('neogen').generate({ type='class' })<CR>", opts)
      vim.api.nvim_set_keymap("n", "<Leader>dom", ":lua require('neogen').generate({ type='file' })<CR>", opts)
      vim.api.nvim_set_keymap("n", "<Leader>dot", ":lua require('neogen').generate({ type='type' })<CR>", opts)
    end,
    -- Uncomment next line if you want to follow only stable versions
    -- version = "*"
  },
  -- 有一些Bug，暂时禁用
  -- { import = "nvchad.blink.lazyspec" },
}
